#include "Scheduler.h"

Scheduler::Scheduler(int numOfProcesses,processDefinition[] processDefs)
{
	n = numOfProcesses;
	procDefs = processDefs;
	procStatistics = 0;
	policy = 0;
	readyQueue = 0;
	blockedQueue = 0;
	globalClock = 0;
}

Scheduler::~Scheduler() {
	for (int i=0; i<n; i++) {
		free(procStatistics.at(i));
	}
}

pid Scheduler::createProcess(pid schedulerPID, processDefinition pDef, int i) {
	pid ans;
	char* argv[11];
	argv[0] = "process";
	argv[1] = itoa(pDef.totalTimeLimit);
	argv[2] = itoa(pDef.initialPriority);
	argv[3] = itoa(pDef.c1);
	argv[4] = itoa(pDef.c2);
	argv[5] = itoa(pDef.b1);
	argv[6] = itoa(pDef.b2);
	argv[7] = itoa(pDef.x0);
	argv[8] = itoa(pDef.y0);
	argv[9] = itoa(pDef.w);
	argv[10] = itoa(schedulerPID);

	ans = fork();
	if (ans==0) {
		execvp("process", argv);
	}

	procStatistics[i] = new processStatistics();
	procStatistics[i].running = 0;
	procStatistics[i].processId = ans;
	procStatistics[i].waitingTime = 0;
	procStatistics[i].averageResponseTime = 0;
	procStatistics[i].turnaroundTime = 0;
	procStatistics[i].garanteedSchedulerFraction = 0;

	return ans;
}

string Scheduler::askForSchedulingPolicy() {
	return "";
}
string Scheduler::askForCPUTimeQuantum() {
	return "";
}

action Scheduler::askForInstructions() {
	return "";
}

void Scheduler::performInstruction(action act) {
	switch (act) {
	case (STATISTICS):
		return printStatistics();
	case (UPLOAD_SETUP_FILE):
		eraseStatistics();
		return run(ASK_FOR_SETUP_FILE);
	case (CHANGE_POLICY):
		eraseStatistics();
		return run(ASK_FOR_POLICY);
	case (CHANGE_QUANTUM):
		eraseStatistics();
		return run(ASK_FOR_QUANTUM);
	case (EXIT):
		return exit();
	}
}
void Scheduler::printStatistics() {
}
void Scheduler::eraseStatistics() {
}
void Scheduler::eraseCurrentProcessDefinitions() {
}
void Scheduler::changePolicy() {
}
void Scheduler::changeQuntum() {
}
void Scheduler::run(runCommand command);
{
	switch (command) {
		case (ASK_FOR_SETUP_FILE):
		askForSetupFile();
		case (READ_SETUP_FILE):
		readSetupFile();
		case (ASK_FOR_POLICY):
		askForSchedulingPolicy();
		case (ASK_FOR_QUANTUM):
		askForCPUTimeQuantum();
		case (CREATE_PROCESSES):
		case (RUN_PROCESSES):
	}
}
pid Scheduler::chooseNextProcessRR() {
}
pid Scheduler::chooseNextProcessGS() {
}
pid Scheduler::chooseNextProcessDMLS() {
}
pid Scheduler::chooseNextProcessPersonal() {
}

void Scheduler::incrementGlobalClock() {
	globalClock++;
}

void Scheduler::suspendRunningProcess() {

}

void Scheduler::updateStatistics() { // signature will probably change

}
void Scheduler::catchSIGUSR1(int num) {

}

void Scheduler::catchSIGUSR2(int num) {
}
void Scheduler::exit() {
}

char* Scheduler::itoa(int val) {
	static char buf[32] = { 0 };
	int i = 30;
	for (; val && i; --i, val /= 10)
		buf[i] = "0123456789abcdef"[val % 10];
	return &buf[i+1];
}

/*
 //string askForSetupFile();
 //void readSetupFile();
 string askForSchedulingPolicy();
 string askForCPUTimeQuantum();

 string askForInstructions();
 void performInstruction(String action);
 void printStatistics();
 void eraseStatistics();
 void eraseCurrentProcessDefinitions();
 void changePolicy();
 void changeQuntum();
 void run(int command); // 1. ask for setup file... etc like in the document.
 pid chooseNextProcessRR();
 pid chooseNextProcessGS();
 pid chooseNextProcessDMLS();
 pid chooseNextProcessPersonal();

 // TODO look at the assignment PS for help!
 void incrementGlobalClock();
 void suspendRunningProcess();
 void updateStatistics(); // signature will probably change
 void catchSIGUSR1(int num);
 void catchSIGUSR2(int num);
 */

